import { ReportData, ErrorInfo, PerformanceInfo, BehaviorInfo, SDKConfig } from '../types';
import { generateSessionId, deepClone } from '../utils';

export class Reporter {
  private config: SDKConfig;
  private sessionId: string;
  private errorCache: ErrorInfo[] = [];
  private performanceCache: PerformanceInfo[] = [];
  private behaviorCache: BehaviorInfo[] = [];
  private reportTimer: number | null = null;
  private isDestroyed = false;

  constructor(config: SDKConfig) {
    this.config = config;
    this.sessionId = generateSessionId();
    this.startReportTimer();
  }

  // 上报错误信息
  public reportError(error: ErrorInfo): void {
    if (this.isDestroyed) return;

    this.errorCache.push(deepClone(error));
    this.checkCacheSize();
  }

  // 上报性能信息
  public reportPerformance(performance: PerformanceInfo): void {
    if (this.isDestroyed) return;

    this.performanceCache.push(deepClone(performance));
    this.checkCacheSize();
  }

  // 上报用户行为
  public reportBehavior(behavior: BehaviorInfo): void {
    if (this.isDestroyed) return;

    this.behaviorCache.push(deepClone(behavior));
    this.checkCacheSize();
  }

  // 检查缓存大小
  private checkCacheSize(): void {
    const maxSize = this.config.maxCacheSize || 100;
    
    if (this.errorCache.length > maxSize) {
      this.errorCache = this.errorCache.slice(-maxSize);
    }
    
    if (this.performanceCache.length > maxSize) {
      this.performanceCache = this.performanceCache.slice(-maxSize);
    }
    
    if (this.behaviorCache.length > maxSize) {
      this.behaviorCache = this.behaviorCache.slice(-maxSize);
    }
  }

  // 开始定时上报
  private startReportTimer(): void {
    const interval = this.config.reportInterval || 5000; // 默认5秒
    
    this.reportTimer = window.setInterval(() => {
      this.flush();
    }, interval);
  }

  // 立即上报所有缓存数据
  public flush(): void {
    if (this.isDestroyed) return;

    const reportData: ReportData = {
      appId: this.config.appId,
      appVersion: this.config.appVersion,
      userId: this.config.userId,
      sessionId: this.sessionId,
      errors: this.errorCache.length > 0 ? [...this.errorCache] : undefined,
      performance: this.performanceCache.length > 0 ? this.performanceCache[this.performanceCache.length - 1] : undefined,
      behaviors: this.behaviorCache.length > 0 ? [...this.behaviorCache] : undefined,
      tags: this.config.tags,
      timestamp: Date.now()
    };

    // 清空缓存
    this.errorCache = [];
    this.performanceCache = [];
    this.behaviorCache = [];

    // 发送数据
    this.sendData(reportData);
  }

  // 发送数据到服务器
  private async sendData(data: ReportData): Promise<void> {
    try {
      const response = await fetch(this.config.reportUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-App-Id': this.config.appId,
          'X-Session-Id': this.sessionId
        },
        body: JSON.stringify(data),
        // 设置超时时间
        signal: AbortSignal.timeout(10000) // 10秒超时
      });

      if (!response.ok) {
        console.warn('Error monitor SDK: Failed to send data', {
          status: response.status,
          statusText: response.statusText
        });
      }
    } catch (error) {
      console.warn('Error monitor SDK: Network error when sending data', error);
      
      // 网络错误时，将数据重新放回缓存
      if (data.errors) {
        this.errorCache.unshift(...data.errors);
      }
      if (data.performance) {
        this.performanceCache.unshift(data.performance);
      }
      if (data.behaviors) {
        this.behaviorCache.unshift(...data.behaviors);
      }
    }
  }

  // 使用Beacon API发送数据（页面卸载时）
  public sendBeacon(): void {
    if (this.isDestroyed) return;

    const reportData: ReportData = {
      appId: this.config.appId,
      appVersion: this.config.appVersion,
      userId: this.config.userId,
      sessionId: this.sessionId,
      errors: this.errorCache.length > 0 ? [...this.errorCache] : undefined,
      performance: this.performanceCache.length > 0 ? this.performanceCache[this.performanceCache.length - 1] : undefined,
      behaviors: this.behaviorCache.length > 0 ? [...this.behaviorCache] : undefined,
      tags: this.config.tags,
      timestamp: Date.now()
    };

    // 清空缓存
    this.errorCache = [];
    this.performanceCache = [];
    this.behaviorCache = [];

    // 使用Beacon API发送数据
    if ('navigator' in window && 'sendBeacon' in navigator) {
      const success = navigator.sendBeacon(
        this.config.reportUrl,
        JSON.stringify(reportData)
      );
      
      if (!success) {
        console.warn('Error monitor SDK: Failed to send beacon data');
      }
    }
  }

  // 获取当前缓存状态
  public getCacheStatus(): {
    errorCount: number;
    performanceCount: number;
    behaviorCount: number;
  } {
    return {
      errorCount: this.errorCache.length,
      performanceCount: this.performanceCache.length,
      behaviorCount: this.behaviorCache.length
    };
  }

  // 销毁上报器
  public destroy(): void {
    this.isDestroyed = true;
    
    if (this.reportTimer) {
      clearInterval(this.reportTimer);
      this.reportTimer = null;
    }
    
    // 发送剩余数据
    this.sendBeacon();
  }
} 